﻿namespace MyServer.Todo.Domain.Aggregates.TodoGroupAggregate
{
    public class TodoGroup:Entity,IAggregateRoot
    {
        private TodoGroup()
        {
            _todos = new List<Todo>();
        }

        public string Name { get;private set; }

        public UserCreationInfo CreationInfo { get; private set; }

        public TodoType TodoType { get; private set; }

        public TodoGroupSettings Settings { get; set; }

        private readonly List<Todo> _todos;
        public IReadOnlyCollection<Todo> Todos => _todos;

        /// <summary>
        /// 创建组
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="name"></param>
        public TodoGroup(string userId,string name):this()
        {
            GenerateId();
            Name = name;
            CreationInfo = new UserCreationInfo(userId,DateTime.Now);
            TodoType = TodoType.Custom;
            Settings = TodoGroupSettings.CreateDefaultSettings();
        }

        /// <summary>
        /// 获取默认组--用户注册的时候用
        /// </summary>
        public static List<TodoGroup> GetDefaultGroups(string userId)
        {
            var groups = new List<TodoGroup>();

            groups.Add(new TodoGroup(userId, TodoType.MyDay.GetDescription()));
            groups.Add(new TodoGroup(userId, TodoType.Important.GetDescription()));
            groups.Add(new TodoGroup(userId, TodoType.Plan.GetDescription()));
            groups.Add(new TodoGroup(userId, TodoType.Todo.GetDescription()));

            return groups;
        }

        /// <summary>
        /// 重命名
        /// </summary>
        /// <param name="name"></param>
        /// <exception cref="Exception"></exception>
        public void Rename(string name)
        {
            if (TodoType != TodoType.Custom)
                throw new Exception("系统默认的待办事项组名称不能修改");
            Name= name;
        }

        public TodoGroup Copy()
        {
            var todoGroup_copy = new TodoGroup(this.CreationInfo.UserId, this.Name);
            todoGroup_copy.Settings = this.Settings.Copy();
            foreach (var todo in this._todos)
            {
                todoGroup_copy._todos.Add(todo.Copy());
            }
            return todoGroup_copy;
        }

        /// <summary>
        ///  删除待办事项
        /// </summary>
        /// <param name="todoId"></param>
        /// <exception cref="ArgumentNullException"></exception>
        public void RemoveTodo(string todoId)
        {
           Todo todo= _todos.FirstOrDefault(_=>_.Id==todoId);
            if (todo == null)
            {
                throw new ArgumentNullException(nameof(todo));
            }
           _todos.Remove(todo);
        }
        /// <summary>
        /// 设置成已完成状态
        /// </summary>
        /// <param name="todoId"></param>
        /// <exception cref="ArgumentNullException"></exception>
        public void SetDoneStatus(string todoId)
        {
            var todo= _todos.FirstOrDefault(_=>_.Id==todoId)??throw new ArgumentNullException();
            todo.SetDoneStatus();
        }

        /// <summary>
        /// 设置为进行中状态
        /// </summary>
        /// <param name="todoId"></param>
        /// <exception cref="ArgumentNullException"></exception>
        public void SetGoingStatus(string todoId)
        {
            var todo = _todos.FirstOrDefault(_ => _.Id == todoId) ?? throw new ArgumentNullException();
            todo.SetGoingStatus();
        }

        /// <summary>
        /// 添加待办事项
        /// </summary>
        /// <param name="name"></param>
        /// <param name="notes"></param>
        /// <exception cref="ArgumentException"></exception>
        public void AddTodo(string name,string notes)
        {
            Todo todo;
            switch (TodoType)
            {
                case TodoType.Custom:
                case TodoType.Todo:
                    todo = new Todo(name, notes);
                    break;
                case TodoType.MyDay:
                    todo=Todo.CreateDayTodo(name, notes);
                    break;
                case TodoType.Important:
                    todo = Todo.CreateImportanceTodo(name, notes);
                    break;
                case TodoType.Plan:
                    todo = Todo.CreatePlanTodo(name, notes);
                    break;
                default:
                    throw new ArgumentException(nameof(TodoType));
            }
            _todos.Add(todo);
        }
    }
}
   